#include "pch.h"
#include "ngx_mem_pool.h"
#include <iostream>
#include <cstring>

// 自定义数据结构，用于测试内存池分配
typedef struct TestData stTestData;
struct TestData {
    char *buffer;
    int *numbers;
    FILE *logFile;
};

// 清理回调函数：释放动态分配的字符数组
void cleanupBuffer(void *data) {
    char *buffer = (char *)data;
    free(buffer);
    std::cout << "Cleaned up buffer memory!" << std::endl;
}

// 清理回调函数：释放动态分配的整数数组
void cleanupNumbers(void *data) {
    int *numbers = (int *)data;
    free(numbers);
    std::cout << "Cleaned up numbers memory!" << std::endl;
}

// 清理回调函数：关闭文件
void cleanupFile(void *data) {
    FILE *file = (FILE *)data;
    if (file) {
        fclose(file);
        std::cout << "Closed file!" << std::endl;
    }
}

int main() {
    // 用例 1：创建内存池并分配小块内存
    {
        ngx_mem_pool memPool{};
        if (memPool.ngx_create_pool(512) == nullptr) {
            std::cerr << "Failed to create memory pool!" << std::endl;
            return -1;
        }

        void *smallBlock = memPool.ngx_palloc(128); // 分配 128 字节
        if (smallBlock == nullptr) {
            std::cerr << "Failed to allocate small block!" << std::endl;
            return -1;
        }
        std::cout << "Small block allocated successfully!" << std::endl;

        // 内存池销毁时会自动释放所有内存
        memPool.ngx_destroy_pool();
        std::cout << "Memory pool destroyed!" << std::endl;
    }

    // 用例 2：分配大块内存并测试外部资源清理
    {
        ngx_mem_pool memPool{};
        if (memPool.ngx_create_pool(1024) == nullptr) {
            std::cerr << "Failed to create memory pool!" << std::endl;
            return -1;
        }

        auto *data = (stTestData *)memPool.ngx_palloc(sizeof(stTestData)); // 分配大块内存
        if (data == nullptr) {
            std::cerr << "Failed to allocate large block!" << std::endl;
            return -1;
        }

        // 分配外部堆内存
        data->buffer = (char *)malloc(256);
        strcpy(data->buffer, "This is a test buffer!");
        data->numbers = (int *)malloc(10 * sizeof(int));
        for (int i = 0; i < 10; ++i) {
            data->numbers[i] = i * i;
        }
        data->logFile = fopen("test_log.txt", "w");

        // 注册清理回调函数
        ngx_pool_cleanup_s *cleanup1 = memPool.ngx_pool_cleanup_add(sizeof(char *));
        cleanup1->handler = cleanupBuffer;
        cleanup1->data = data->buffer;

        ngx_pool_cleanup_s *cleanup2 = memPool.ngx_pool_cleanup_add(sizeof(int *));
        cleanup2->handler = cleanupNumbers;
        cleanup2->data = data->numbers;

        ngx_pool_cleanup_s *cleanup3 = memPool.ngx_pool_cleanup_add(sizeof(FILE *));
        cleanup3->handler = cleanupFile;
        cleanup3->data = data->logFile;

        std::cout << "Large block and external resources allocated successfully!" << std::endl;

        // 内存池销毁时会自动调用清理回调函数
        memPool.ngx_destroy_pool();
        std::cout << "Memory pool destroyed and resources cleaned up!" << std::endl;
    }

    // 用例 3：测试内存池的边界条件
    {
        ngx_mem_pool memPool{};
        if (memPool.ngx_create_pool(256) == nullptr) {
            std::cerr << "Failed to create memory pool!" << std::endl;
            return -1;
        }

        // 尝试分配超过内存池大小的内存块
        void *largeBlock = memPool.ngx_palloc(512); // 超过 256 字节
        if (largeBlock == nullptr) {
            std::cout << "Failed to allocate large block (expected behavior)!" << std::endl;
        }

        // 分配小块内存
        void *smallBlock = memPool.ngx_palloc(64); // 64 字节
        if (smallBlock == nullptr) {
            std::cerr << "Failed to allocate small block!" << std::endl;
            return -1;
        }
        std::cout << "Small block allocated successfully!" << std::endl;

        memPool.ngx_destroy_pool();
        std::cout << "Memory pool destroyed!" << std::endl;
    }

    // 用例 4：测试多次分配和释放
    {
        ngx_mem_pool memPool{};
        if (memPool.ngx_create_pool(1024) == nullptr) {
            std::cerr << "Failed to create memory pool!" << std::endl;
            return -1;
        }

        for (int i = 0; i < 10; ++i) {
            void *block = memPool.ngx_palloc(64); // 每次分配 64 字节
            if (block == nullptr) {
                std::cerr << "Failed to allocate block in iteration " << i << "!" << std::endl;
                return -1;
            }
            std::cout << "Block allocated in iteration " << i << "!" << std::endl;
        }

        memPool.ngx_destroy_pool();
        std::cout << "Memory pool destroyed after multiple allocations!" << std::endl;
    }

    return 0;
}